﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TicketsPhone.Domain.Entities;
using System.Data;
using TicketsPhone.Domain.Utils;
using TicketsPhone.Domain.Models;
using TicketsPhone.Entidades;

namespace TicketsPhone.Domain.Access
{
    public class SucursalRepositorio : ConexionSql<Sucursal>,  ICrud<Sucursal>
    {

        public SucursalRepositorio()
        {
            Objeto = new Sucursal();
            Objeto.Entidad = new EntidadRelacional();    
        }


        public int Crear()
        {
            CrearComando("spSucursal_Crear");
            AgregarParametros();
            return Convert.ToInt32(ExecuteScalar());
        }

        public bool Editar()
        {
            CrearComando("spSucursal_Editar");
            AgregarParametros();
            return ExecuteNonQuery() > 0;
        }

        public bool Eliminar(int id)
        {
            CrearComando("spSucursal_Eliminar");
            AgregarParametro("@IdSucursal", id, ParameterDirection.Input, DbType.Int32);
            return ExecuteNonQuery() > 0;
        }

        public Sucursal Cargar(int id)
        {
            Sucursal objeto = new Sucursal();
            CrearComando("spSucursal_Cargar");
            AgregarParametro("@IdSucursal", id, System.Data.ParameterDirection.Input, System.Data.DbType.Int32);
            ExecuteReader();

            while (Read())
            {
                objeto = new Sucursal(GetDataReader());
            }

            return objeto;
        }

        public List<Sucursal> ObtenerTodos()
        {
            throw new NotImplementedException();
        }


        public List<Sucursal> Filtrar()
        {
            List<Sucursal> lista = new List<Sucursal>();
            CrearComando("spSucursal_Filtrar");
            AgregarParametro("@Nombre", Objeto.Nombre, System.Data.ParameterDirection.Input, System.Data.DbType.String);
            AgregarParametro("@IdEntidad", Objeto.Entidad.IdEntidad, System.Data.ParameterDirection.Input, System.Data.DbType.Int32);
            ExecuteReader();

            while (Read())
            {
                Sucursal obj = new Sucursal();
                obj.IdSucursal = GetIntValue("IdSucursal");
                obj.Nombre = GetStringValue("Nombre");
                obj.Entidad.Nombre = GetStringValue("NombreEntidad");
                obj.Direccion = GetStringValue("Direccion");
                obj.Telefono = GetStringValue("Telefono");
                obj.Ciudad.Nombre = GetStringValue("NombreCiudad");
                obj.FechaModificacion = GetDateValue("FechaModificacion");
                lista.Add(obj);
            }

            return lista;
        }

        /// <summary>
        /// Retorna todos los tramites existentes con la propiedad "Activo" en "true" para los tramites asignados a la sucursal
        /// </summary>
        /// <param name="idSucursal">id de la suscursal que se desean traer los tramites asignados</param>
        /// <returns>Listado de tramites</returns>
        public List<TramitesSucursal> ObtenerTramitesAsignados(int idSucursal)
        {
            List<TramitesSucursal> lista = new List<TramitesSucursal>();
            CrearComando("spSucursal_ObtenerTramitesAsignados");
            AgregarParametro("@IdSucursal", idSucursal, System.Data.ParameterDirection.Input, System.Data.DbType.Int32);
            ExecuteReader();

            while (Read())
            {
                TramitesSucursal obj = new TramitesSucursal();
                obj.Tramite.IdTramite = GetIntValue("IdTramite");
                obj.Tramite.Nombre = GetStringValue("Nombre");
                obj.Activo = GetBooleanValue("Activo");
                lista.Add(obj);
            }

            return lista;
        }

        /// <summary>
        /// Asigna un tramite a una sucursal
        /// </summary>
        /// <param name="idTramite">id del tramite a desasignar</param>
        /// <param name="idSucursal">id de la sucursal</param>
        /// <returns></returns>
        public bool AsignarTramite(int idTramite, int idSucursal)
        {
            CrearComando("spSucursal_AsignarTramite");
            AgregarParametro("@IdSucursal", idSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTramite", idTramite, ParameterDirection.Input, DbType.Int32);
            return ExecuteNonQuery() > 0;
        }

        /// <summary>
        /// Actualiza el valor del turno en una de las cajas
        /// </summary>
        /// <returns></returns>
        public bool EditarTurnoEnCaja(int caja, int idTurno, int idSucursal)
        {
            CrearComando("spSucursal_EditarTurnoEnCaja");
            AgregarParametro("@IdSucursal", idSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTurno", idTurno, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Caja", caja, ParameterDirection.Input, DbType.Int32);
            return ExecuteNonQuery() > 0;
        }

        /// <summary>
        /// Elimina la asignacion de un tramite a una sucursal
        /// </summary>
        /// <param name="idTramite">id del tramite a desasignar</param>
        /// <param name="idSucursal">id de la sucursal</param>
        /// <returns></returns>
        public bool EliminarTramite(int idTramite, int idSucursal)
        {
            CrearComando("spSucursal_EliminarTramite");
            AgregarParametro("@IdSucursal", idSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTramite", idTramite, ParameterDirection.Input, DbType.Int32);
            return ExecuteNonQuery() > 0;
        }

        /// <summary>
        /// Retorna el listado de horas en las q tiene atención al publico la sucursal
        /// </summary>
        /// <param name="idSucursal">id de la sucursal</param>
        /// <returns>listado de horarios</returns>
        public List<Horario> ObtenerHorario(int idSucursal)
        {
            List<Horario> lista = new List<Horario>();
            CrearComando("spSucursal_ObtenerHorario");
            AgregarParametro("@IdSucursal", idSucursal, System.Data.ParameterDirection.Input, System.Data.DbType.Int32);
            ExecuteReader();

            while (Read())
            {
                Horario obj = new Horario();
                obj.IdHorario = GetIntValue("IdHorario");
                obj.Sucursal.IdSucursal = GetIntValue("IdSucursal");
                obj.Dia = (DayOfWeek) GetIntValue("Dia");
                obj.HoraInicio = GetTimeValue("HoraInicio");
                obj.HoraFin = GetTimeValue("HoraFin");
                obj.CajerosActivos = GetIntValue("CajerosActivos");
                lista.Add(obj);
            }

            return lista;
        }

        /// <summary>
        /// Guarda los datos de un horario
        /// </summary>
        /// <param name="obj">Datos del horario a guardar</param>
        public void EditarHorario(Horario obj)
        {
            CrearComando("spSucursal_EditarHorario");
            AgregarParametro("@IdHorario", obj.IdHorario, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Dia", obj.Dia, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@HoraInicio", obj.HoraInicio.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@HoraFin", obj.HoraFin.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@IdSucursal", obj.Sucursal.IdSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@CajerosActivos", obj.CajerosActivos, ParameterDirection.Input, DbType.Int32);
            ExecuteNonQuery();
        }

        /// <summary>
        /// Inserta un horario asignada a una sucursal
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int InsertarHorario(Horario obj)
        {
            CrearComando("spSucursal_InsertarHorario");
            AgregarParametro("@Dia", obj.Dia, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@HoraInicio", obj.HoraInicio.ToDateTime(), ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@HoraFin", obj.HoraFin.ToDateTime(), ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@IdSucursal", obj.Sucursal.IdSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@CajerosActivos", obj.CajerosActivos, ParameterDirection.Input, DbType.Int32);
            return Convert.ToInt32(ExecuteScalar());
        }

        /// <summary>
        /// Cuenta el numero de cajeros activos en una sucursal dependiendo de la Hora de Inicio de la Solicitud
        /// </summary>
        /// <param name="obj">Horario en el que se esta solicitando el turno, y sobre el cual se va a validar cuantos cajeros activos hay</param>
        /// <returns>número de cajeros activos</returns>
        public int ObtenerCajerosActivos(Horario obj)
        {
            CrearComando("spSucursal_ObtenerCajerosActivos");
            AgregarParametro("@Dia", obj.Dia, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@HoraInicio", obj.HoraInicio.ToDateTime(), ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@HoraFin", obj.HoraFin.ToDateTime(), ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@IdSucursal", obj.Sucursal.IdSucursal, ParameterDirection.Input, DbType.Int32);
            return Convert.ToInt32(ExecuteScalar());
        }

        public List<CajeroActivo> ObtenerInfoCajeros(int idSucursal)
        {
            List<CajeroActivo> lista = new List<CajeroActivo>();
            CrearComando("spSucursal_ObtenerInfoCajeros");
            AgregarParametro("@IdSucursal", idSucursal, System.Data.ParameterDirection.Input, System.Data.DbType.Int32);
            ExecuteReader();

            while (Read())
            {
                CajeroActivo obj = new CajeroActivo();
                obj.Codigo = GetStringValue("Codigo");
                obj.IdTurno = GetValue("IdTurno") == DBNull.Value ? 0 : GetIntValue("IdTurno");
                obj.NumCaja = GetIntValue("Caja");
                lista.Add(obj);
            }

            return lista;
               
        }

        /// <summary>
        /// INserta los cajeros necesarios en una sucursal
        /// </summary>
        /// <param name="idSucursal"></param>
        /// <param name="cajas"></param>
        public void InsertarCajerosPorTurno(int idSucursal, int cajas)
        {
            for (int i = 1; i < cajas + 1; i++)
            {
                CrearComando("spSucursal_InsertarCajerosPorTurno");
                AgregarParametro("@IdSucursal", idSucursal, ParameterDirection.Input, DbType.Int32);
                AgregarParametro("@caja", i, ParameterDirection.Input, DbType.Int32);
                ExecuteNonQuery();
            }
            
        }

        public void GuardarTransaccion(TipoTransaccion tipoTransaccion)
        {
            throw new NotImplementedException();
        }

        public void AgregarParametros()
        {
            AgregarParametro("@IdSucursal", Objeto.IdSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Nombre", Objeto.Nombre, ParameterDirection.Input, DbType.String);
            AgregarParametro("@Direccion", Objeto.Direccion, ParameterDirection.Input, DbType.String);
            AgregarParametro("@Telefono", Objeto.Telefono, ParameterDirection.Input, DbType.String);
            AgregarParametro("@IdTipoCentro", Objeto.IdTipoCentro, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdCiudad", Objeto.Ciudad.IdCiudad, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Descripcion", Objeto.Descripcion, ParameterDirection.Input, DbType.String);
            AgregarParametro("@IdEntidad", Objeto.Entidad.IdEntidad, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Activo", Objeto.Activo, ParameterDirection.Input, DbType.Boolean);
            AgregarParametro("@FechaModificacion", Objeto.FechaModificacion, ParameterDirection.Input, DbType.DateTime);
        }
    }
}
